//###############
//FILE : NameWantFileSession.java
//WRITER : Daniel Lowengrub, daniel_i_l, 320687098
//EXERCISE : oop ex3 2011
//DESCRIPTION:
//See below
//###############

package oop.ex3.protocol.sessions;

import oop.ex3.protocol.messages.WantFileMsg;
import oop.ex3.protocol.messages.FileAddressMsg;
import oop.ex3.protocol.messages.FileNotFoundMsg;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import oop.ex3.communication.SocketAddress;
import oop.ex3.exceptions.InvalidMessageException;
import oop.ex3.nameserver.NameServerDatabase;

/**
 * Send the FM a list of Fm's that contain a specific file.
 * @author daniel
 */
public class NameWantFileSession extends NameToFileSession {
    private NameServerDatabase _nameServerDb;

    /**
	 * Create a new session.
	 */
    public NameWantFileSession() {
        super(new WantFileMsg());
    }

    /**
     * Set the database to use for looking up FMs.
     * @param nameDb The NS database.
     */
    public void setNameServerDatabase(NameServerDatabase nameDb) {
        _nameServerDb = nameDb;
    }

    @Override
    protected boolean specExecuteSession(DataInputStream inputStream, DataOutputStream outputStream) throws IOException, InvalidMessageException {
        WantFileMsg wantFile = new WantFileMsg();
        wantFile.receive(inputStream);
        String fileName = wantFile.getFileName();
        ArrayList<SocketAddress> fileManagers = _nameServerDb.getManagersWithFile(fileName);

        //if we received the request then send the list
        if (fileManagers.size() == 0) {
            FileNotFoundMsg noFile = new FileNotFoundMsg();
            noFile.send(outputStream);
            return true;
        }


        for (SocketAddress address : fileManagers) {
            FileAddressMsg fileAddr = new FileAddressMsg();
            fileAddr.setIp(address.getIp());
            fileAddr.setPort(address.getPort());
            fileAddr.send(outputStream);
        }


        _endList.send(outputStream);

        return true;
    }

}
